<?php

namespace app\common\service\word;

use app\common\service\ApiService;
use think\facade\Request;

class WordUtilsService extends ApiService
{
    private const MD5_KEY = "yingyu";
    private const WORD_VOCAL_OSS_KEY = "word_vocal";

    /**
     * 48音标
     */
    private const PHONETIC_SYMBOLS = [
        "i:", "ɪ", "e", "æ",
        "ɜː", "ə", "ʌ",
        "u:", "ʊ", "ɔː", "ɒ", "ɑː",
        "eɪ", "aɪ", "ɔɪ", "aʊ", "əʊ",
        "ɪə", "eə", "ʊə",
        "p", "t", "k",
        "b", "d", "g",
        "f", "s", "ʃ", "θ", "h",
        "v", "z", "ʒ", "ð", "r",
        "tʃ", "tr", "ts",
        "dʒ", "dr", "dz",
        "m", "n", "ŋ",
        "l",
        "j", "w"
    ];

    private static ?string $domain = null;

    /**
     * 获取域名
     */
    private static function getDomain(): string
    {
        if (self::$domain === null) {
            // 从配置中获取域名
            self::$domain = Request::domain();
        }
        return self::$domain;
    }

    /**
     * 音标过滤
     */
    public static function getFilterPhonetic(?string $text): string
    {
        if (empty($text)) {
            return "";
        }
        return preg_replace("/[\/\[\]]/", "", $text);
    }

    /**
     * 音标填充
     */
    public static function getFillPhonetic(?string $text): string
    {
        if (empty($text)) {
            return "";
        }
        $filtered = preg_replace("/[\/\[\]]/", "", $text);
        return "/{$filtered}/";
    }

    /**
     * 获取音标，音节发音资源
     */
    public static function getPhoneticVocalUrl(?string $text, string $resourceType): string
    {
        if (empty($text)) {
            return "";
        }

        $filtered = self::getFillPhonetic($text);
        $encode = urlencode($filtered);
        $domain = self::getDomain();

        return "{$domain}/common_api/dictionary/wordResources/getVocal?text={$encode}&resourcesType={$resourceType}&server=1";
    }

    /**
     * 获取文本发音资源
     */
    public static function getVocalUrl(?string $text, string $resourceType): string
    {
        if (empty($text)) {
            return "";
        }

        $domain = self::getDomain();
        return "{$domain}/common_api/dictionary/wordResources/getVocal?text={$text}&resourcesType={$resourceType}&server=1";
    }

    /**
     * 获取单词发音OSS储存位置
     */
    public static function getSyllableVocalOssKey(string $word, string $fileType): string
    {
        return self::WORD_VOCAL_OSS_KEY . "/" . self::getWordMd5Name($word . "_Syllable") . "." . $fileType;
    }

    /**
     * 获取单词发音OSS储存位置
     */
    public static function getVocalOssKey(string $word, string $fileType): string
    {
        return self::WORD_VOCAL_OSS_KEY . "/" . self::getWordMd5Name($word) . "." . $fileType;
    }

    /**
     * 获取单词 md5 名称
     */
    public static function getWordMd5Name(string $word): string
    {
        return md5($word . self::MD5_KEY);
    }

    /**
     * 获取文章单词数量
     */
    public static function getArticleWordNum(string $content): int
    {
        // 转换为小写
        $content = strtolower($content);

        // 使用正则表达式分割句子为单词数组
        $words = preg_split("/\W+/", $content, -1, PREG_SPLIT_NO_EMPTY);

        return count($words);
    }

    /**
     * 将给定的字符串随机拆分为指定数量的部分
     *
     * @param string $input 待拆分的字符串
     * @param int $parts 指定拆分的段数
     * @return array 包含多个字符串部分的列表
     */
    public static function splitStringIntoParts(string $input, int $parts): array
    {
        if (empty($input) || strlen($input) < $parts) {
            throw new \InvalidArgumentException("字符串太短或为空，无法按照要求拆分");
        }
        if ($parts < 2) {
            throw new \InvalidArgumentException("拆分段数必须大于等于2");
        }

        $indices = [0];
        $inputLength = strlen($input);

        while (count($indices) < $parts) {
            $newIndex = random_int(1, $inputLength - 2);
            if (!in_array($newIndex, $indices)) {
                $indices[] = $newIndex;
            }
        }

        // 添加末尾索引
        $indices[] = $inputLength;

        // 排序以确保顺序正确
        sort($indices);

        $result = [];
        for ($i = 0; $i < count($indices) - 1; $i++) {
            $part = substr($input, $indices[$i], $indices[$i + 1] - $indices[$i]);
            $result[] = $part;
        }

        return $result;
    }

    /**
     * 拆分音标
     */
    public static function phoneticSplit(string $phonetic): array
    {
        $result = [];
        $i = 0;
        $phoneticLength = strlen($phonetic);

        while ($i < $phoneticLength) {
            $matched = false;

            // 尝试匹配最长可能的音素
            for ($j = min(3, $phoneticLength - $i); $j > 0; $j--) {
                $candidate = substr($phonetic, $i, $j);
                if (in_array($candidate, self::PHONETIC_SYMBOLS)) {
                    $result[] = "/{$candidate}/";
                    $i += $j;
                    $matched = true;
                    break;
                }
            }

            if (!$matched) {
                // 如果没有匹配到任何音素，则跳过当前字符
                $i++;
            }
        }

        return $result;
    }

    /**
     * 获取单词首字母
     */
    public static function getFirstLetter(?string $word): string
    {
        if (empty($word)) {
            return "";
        }

        // 获取第一个字母（A-Z a-z），如果第一个字不是字母，则往下找，找不到的话返回空
        for ($i = 0; $i < strlen($word); $i++) {
            $char = $word[$i];
            if (ctype_alpha($char)) {
                return $char;
            }
        }

        return "";
    }
}
